package com.xygz.orm;

import com.xiyuan.smartutils.paging.PageResult;
import com.xygz.orm.exception.ORMException;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

/**
 * DQL英文全称是Data Query Language(数据查询语言)，数据查询语言，用来查询数据库中表的记录。
 *
 * @author xiyuan-lgz 2023-10-01 @version v1.0.0 新建与整理
 */
@SuppressWarnings("all")
public interface DQL {
    
    /********************************************************************************************/
    // item 查询一条数据
    /********************************************************************************************/
    
    /**
     * 通过主键ID查询一条记录
     *
     * @param clz                   表类
     * @param id                    表主键主键
     * @return                      返回表对象
     * @throws ORMException         ORM异常
     * @throws SQLException         数据库异常
     */
    public <E> E one(Class<E> clz, Serializable id) throws ORMException, SQLException;
    
    /**
     * 查询一条记录
     *
     * @param clz 表类
     * @return 返回表对象
     * @throws ORMException         ORM异常,如果传入的属性不在配置文件中则异常
     * @throws SQLException         数据库异常
     */
    default <E> E one(Class<E> clz) throws ORMException, SQLException {
        return one(Selector.of(clz));
    }
    
    /**
     * 查询一个表对象，并指定返回属性,查询条件和排序条件
     *
     * @param selector              对象查询器
     * @return                      返回表对象
     * @throws ORMException         ORM异常,如果传入的属性不在配置文件中则异常
     */
    default <E, Q extends Selector<E>> E one(Q selector) throws ORMException{
        List<E> list = list(selector, 1, 1);
        return list.isEmpty() ? null : list.get(0);
    }
    
    /********************************************************************************************/
    // list 查询列表
    /********************************************************************************************/
    
    /**
     * 查询表对象列表，全表查询
     *
     * @param cls                   表类
     * @return                      返回表对象列表
     * @throws ORMException         ORM异常
     * @throws SQLException         数据库异常
     */
    default <E> List<E> list(Class<E> cls) throws ORMException, SQLException {
        return list(Selector.of(cls));
    }
    
    /**
     * 查询表对象列表，指定页数，条目查询
     *
     * @param table    表类
     * @param pageNo   分页数
     * @param pageSize 分页大小
     * @param <E>      表类型
     * @return 对象列表
     * @throws ORMException         ORM 异常
     * @throws SQLException         数据库异常
     */
    default <E> List<E> list(Class<E> table, int pageNo, int pageSize) throws ORMException, SQLException {
        return list(Selector.of(table), pageNo, pageSize);
    }
    
    /**
     * 查询表对象列表，指定页数，条目查询
     *
     * @param table                 查询表
     * @param pageNo                分页数
     * @param pageSize              分页大小
     * @param target                结果集表类
     * @param <E>                   表类型
     * @return 对象列表
     * @throws ORMException         ORM 异常
     * @throws SQLException         数据库异常
     */
    default <E, T> List<E> list(Class<T> table, int pageNo, int pageSize, Class<E> target) throws
                                                                                           ORMException,
                                                                                           SQLException {
        return list(Selector.of(table), pageNo, pageSize, target);
    }
    
    /**
     * 查询表对象列表，并指定返回属性,查询条件和排序条件
     *
     * @param selector              对象查询器
     * @return                      返回表对象列表
     * @throws ORMException         ORM异常
     * @throws SQLException         数据库异常
     */
    public <E, Q extends Selector<E>> List<E> list(Q selector) throws ORMException, SQLException;
    
    /**
     * 查询数据列表，并根据指定类型返回结果集
     *
     * @param target                指定结果集类型
     * @param selector              查询器
     * @return 数据列表
     * @throws ORMException         ORM异常
     * @throws SQLException         数据库异常
     */
    public <E, Q extends Selector<?>> List<E> list(Class<E> target, Q selector) throws ORMException, SQLException;
    
    /**
     * 指定页数、条目，查询器，查询结果列表
     *
     * @param pageNo                分页数
     * @param pageSize              分页大小
     * @param selector              对象查询器
     * @return                      返回表对象列表
     * @throws ORMException         ORM异常,如果传入的属性不在配置文件中则异常
     */
    public <E, Q extends Selector<E>> List<E> list(Q selector, int pageNo, int pageSize) throws ORMException;
    
    /**
     * 指定页数、条目，查询器，查询结果列表并根据指定类型返回结果集
     *
     * @param selector              对象查询器
     * @param pageNo                分页数
     * @param pageSize              分页大小
     * @param target                指定结果集类型
     * @return                      返回表对象列表
     * @throws ORMException         ORM异常,如果传入的属性不在配置文件中则异常
     */
    public <E, Q extends Selector<?>> List<E> list(Q selector, int pageNo, int pageSize, Class<E> target) throws
                                                                                                          ORMException;
    
    /********************************************************************************************/
    // page 分页显示
    /********************************************************************************************/
    
    /**
     * 分页查询数据
     *
     * @param clz                   查询表
     * @param pageNo                分页数
     * @param pageSize              分页大小
     * @param <T>                   数据类型
     * @return 数据列表
     * @throws ORMException         ORM异常
     */
    default <T> PageResult<T> page(Class<T> clz, int pageNo, int pageSize) throws ORMException {
        return page(Selector.of(clz), pageNo, pageSize);
    }
    
    /**
     * 分页查询数据
     *
     * @param table                 查询表
     * @param pageNo                分页数
     * @param pageSize              分页大小
     * @param target                结果集类型
     * @param <T>                   数据类型
     * @return 数据列表
     * @throws ORMException         ORM异常
     */
    default <T, E> PageResult<T> page(Class<E> table, int pageNo, int pageSize, Class<T> target) throws ORMException {
        return page(Selector.of(table), pageNo, pageSize, target);
    }
    
    /**
     * 分页查询数据
     *
     * @param selector              查询器
     * @param pageNo                分页数
     * @param pageSize              分页大小
     * @param <E>                   数据类型
     * @return                      数据列表
     * @throws ORMException         ORM异常
     */
    public <E, Q extends Selector<E>> PageResult<E> page(Q selector, int pageNo, int pageSize) throws ORMException;
    
    /**
     * 分页查询数据指定类型返回结果集
     *
     * @param target                指定接收结果集类型
     * @param selector              查询器
     * @param pageNo                分页数
     * @param pageSize              分页大小
     * @param <E>                   数据类型
     * @return 数据列表
     * @throws ORMException         ORM异常
     */
    public <E, Q extends Selector<?>> PageResult<E> page(Q selector, int pageNo, int pageSize, Class<E> target) throws ORMException;
    
    /********************************************************************************************/
    // count 查询数目
    /********************************************************************************************/
    
    /**
     * 更具查询条件，查询数目
     *
     * @param selector              条件查询器
     * @return                      查询数目
     * @throws ORMException         ORM异常
     */
    public <Q extends Selector<?>> long count(Q selector) throws ORMException;
    
    /**
     * 查询数目，整表查询
     *
     * @param clz                   表类
     * @return                      存在的数目
     * @throws ORMException         ORM异常
     */
    default <E> long count(Class<E> clz) throws ORMException {
        return count(Selector.of(clz));
    }

//    /********************************************************************************************/
//    //sum 计算总和
//    /********************************************************************************************/


//    /**
//     * 计算总和
//     *
//     * @param cls   表类
//     * @param field 表字段
//     * @return 计算总和
//     * @throws ORMException ORM异常
//     * @throws SQLException 数据库异常
//     */
//    public long sum(Class<?> cls, String field) throws ORMException, SQLException;
//
//    /**
//     * 计算总和
//     *
//     * @param cls      表类
//     * @param selector 对象查询器
//     * @param field    表字段
//     * @return 计算总和
//     * @throws ORMException ORM异常
//     * @throws SQLException 数据库异常
//     */
//    public long sum(Class<?> cls, Selector selector, String field) throws ORMException, SQLException;
//
//    /**
//     * 计算多个总和
//     *
//     * @param cls      表类
//     * @param selector 对象查询器
//     * @param fields   多个表字段
//     * @return 计算多个总和
//     * @throws ORMException ORM异常
//     * @throws SQLException 数据库异常
//     */
//    public long[] sum(Class<?> cls, Selector selector, String... fields) throws ORMException, SQLException;
}
